#!/usr/bin/env python
# coding=UTF-8
import os
import logging
import logging.handlers
from optparse import OptionParser
import json
import time
import threading

from nsq.reader import Reader
from apscheduler.scheduler import Scheduler

import config
import views

def initLog(options):
    filename = "%s_%s" % (options.logfile, options.port)
    log_path = os.path.dirname(filename)
    if not os.path.isdir(log_path):
        os.makedirs(log_path)
    logger = logging.getLogger()
    hdlr = logging.handlers.TimedRotatingFileHandler(filename, when='midnight', backupCount=options.backupCount)
    formatter = logging.Formatter("[%(asctime)s]: %(module)s %(levelname)s %(message)s ")
    hdlr.setFormatter(formatter)
    logger.addHandler(hdlr)
    if options.debug:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)
        
func_conf = {'status':{'create_room':views.create_room,
                     'join_room':views.join_room,
                     'quit_room':views.quit_room,
                     'dismiss_room':views.dismiss_room,
                     'ready':views.ready,
                     'start_match':views.start_match,
                     'stop_match':views.stop_match,
             },
             'login':{'default':views.online,
                      'login':views.online,
                      },
             'offline':{'default':views.offline,
                        'offline':views.offline,
                        },
             'im':{'im_chat':views.im_chat,
                   'default':views.im_chat,
                   },
             'game':{
                 'create_room':views.create_room,
                  'join_room':views.join_room,
                    'quit_room':views.quit_room,
                    'ready':views.ready,
                     'pass':views.game_act,
                     'put_card':views.game_act,
                     'get_last_data':views.ready,
                     'pair':views.game_act,
                     'dark_bar':views.game_act,
                     'pair_bar':views.game_act,
                     'pair_bar_win':views.game_act,
                     'bar':views.game_act,
                     'win':views.game_act,
                     'put_win':views.game_act,
                     'game_start':views.game_act,
                     'eat':views.game_act,
                     'cancel_rob':views.game_act,
                     'rob_landlord':views.game_act,
                     'double_select':views.game_act,
                     'rob':views.game_act,
                     'show_res':views.game_act,
                     'dismiss_apply':views.dismiss_apply,
                     'dismiss_agree':views.dismiss_agree,
                     'dismiss_refuse':views.dismiss_refuse,
                     'dismiss_room':views.dismiss_room,
                     },
             
             'total':{
                   'default':views.client_report,
                   },
             'game_start':{
                   'game_start':views.game_start,
                   },
             }


def consumer(topic='status', channel='py'):
    try:
        reader = Reader(topic, channel, nsqd_tcp_addresses=[config.NSQ_ADDR, ])
        for message in reader:
            try:
                print message.body,"###########################"
                msg = json.loads(message.body)
                bid = msg.get('b', '')
                uid = msg.get('u', '')
                data = msg.get('d',{})
                act = data.get('act')
                if not act:
                    act = 'default'
                if "game" in topic:
                    topic = "game"
                topic_handler = func_conf.get(topic, {})
                handler = topic_handler.get(act)
                if not handler:
                    logging.error(u"404 没有对应处理方法,topic:%s,act:%s,msg:%s" % (topic, act, message.body))
                else:
                    logging.info(u"收到消息:topic:%s,msg:%s" % (topic, message.body))
                    handler(reader, bid, uid, data)
                
            except:
                logging.error("nsq handler error", exc_info=True)
            finally:
                message.fin()
        
    except:
        logging.error("nsq error=================", exc_info=True)
        
def main():
    parser = OptionParser(usage="usage: python %prog [options] filename", version="mserver v1.0.0")
    parser.add_option("-p", "--port",
                      action="store",
                      type="int",
                      dest="port",
                      default=3333,
                      help="Listen Port")
    parser.add_option("-f", "--logfile",
                      action="store",
                      type="string",
                      dest="logfile",
                      default='./logs/run.log',
                      help="LogFile Path and Name. default=./run.log")
    parser.add_option("-n", "--backupCount",
                      action="store",
                      type="int",
                      dest="backupCount",
                      default=10,
                      help="LogFile BackUp Number")
    parser.add_option("-m", "--master",
                      action="store_true",
                      dest="master",
                      default=False,
                      help="master process")
    parser.add_option("-d", "--debug",
                          action="store_true",
                          dest="debug",
                          default=True,
                          help="debug mode")
    (options, args) = parser.parse_args()
    initLog(options)
    
    channel = 'py6'
    for game_type in config.GAME_TYPE_NAME.keys():
        if game_type == 'pdk':
            threading.Thread(target=consumer, args=('game_%s' % game_type, channel)).start()
        threading.Thread(target=consumer, args=('game_%s' % game_type, channel)).start()
    threading.Thread(target=consumer, args=('status', channel)).start()
    threading.Thread(target=consumer, args=('im', channel)).start()
    threading.Thread(target=consumer, args=('game', channel)).start()
    threading.Thread(target=consumer, args=('login', channel)).start()
    threading.Thread(target=consumer, args=('offline', channel)).start()
    threading.Thread(target=consumer, args=('total', channel)).start()
    threading.Thread(target=consumer, args=('game_start', channel)).start()
    sched = Scheduler()
    sched.add_cron_job(views.job_dismiss_room, second='*/5')
    sched.add_cron_job(views.job_cron, second='*/5')
    sched.add_cron_job(views.del_game_cron, second='*/30')
    sched.daemonic = False
    sched.start()
if __name__ == "__main__":
    main()
        
